package tutorial.bot;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.methods.groupadministration.GetChat;
import org.telegram.telegrambots.meta.api.methods.groupadministration.GetChatAdministrators;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.methods.updatingmessages.DeleteMessage;
import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText;
import org.telegram.telegrambots.meta.api.objects.*;
import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMember;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import tutorial.bean.SellVO;
import tutorial.utils.InterfaceUtils;
import tutorial.utils.JedisUtils;
import tutorial.utils.MathUtils;

import javax.script.ScriptException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLOutput;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: dingziyuan
 * @Date: 2023/11/1/001 14:45
 * @Description: *
 */
public class Bot extends TelegramLongPollingBot {


    private InlineKeyboardMarkup keyboardM1;


    @Override
    public String getBotUsername() {
        return "guanbo_bot";
    }

    @Override
    public String getBotToken() {
        return "6885156383:AAGQeI7sUDaMjnvKDiKbhd4hmTHjk7NnBls";
    }

    @Override
    public void onUpdateReceived(Update update) {
        System.out.println("==========进入update===============");
        System.out.println("=============收到回调消息=========" + update.getCallbackQuery());

        if (update.hasMessage() && update.getMessage().hasText()) {
            final Message msg = update.getMessage();

            System.out.println("=============收到消息=========" + msg);
            // 机器人必须是管理员
            if (!"private".equals(msg.getChat().getType())) {
                if (!robotIsAdmin(msg.getChatId())) {
                    return;
                }
            }
            fourOperationsHandler(msg);
            keyboardTextHandler(msg);
            if ("/start".equals(msg.getText())) {
                createButton();
                sendButton(msg.getChat().getId(), "\uD83E\uDD16欢迎使用<a href=\"https://t.me/ndjd7375\">小天机器人</a>，快把我加入群组吧！", keyboardM1);

                if ("private".equals(msg.getChat().getType())) {
                    sendCustomKeyboard(msg.getChat().getId());
                }

                if ("group".equals(msg.getChat().getType()) || "supergroup".equals(msg.getChat().getType()) ) {
                    initData(msg);
                }
            }

            // 如果是群组
            if ("group".equals(msg.getChat().getType())|| "supergroup".equals(msg.getChat().getType())) {
                System.out.println("进入群组~！111");
                groupAuthTextHandler(msg);
                bookkeepingModelHandler(msg);
                setUpRateHandler(msg);
                setMoneyHandler(msg);
                clearDataHandler(msg);
                rateConversionHandler(msg);
            }
        }
        if (update.hasCallbackQuery()) {
            final CallbackQuery query = update.getCallbackQuery();
            final Message message = query.getMessage();
            // 机器人必须是管理员
            if (!robotIsAdmin(message.getChatId())) {
                return;
            }
            // 如果是群组
            if ("group".equals(message.getChat().getType()) || "supergroup".equals(message.getChat().getType()) ) {
                System.out.println("进入回调群组~！！！");
                if (authHandler(message,String.valueOf(query.getFrom().getId()))) {
                    bookkeepingCallbackHandler(update.getCallbackQuery());
                    clearDataCallBackHandler(update.getCallbackQuery());
                    clearDataCallBackHandlerEnd(update.getCallbackQuery());
                }

            }
        }

    }

    private void initData(Message msg) {
        // 设置记账模式
        JedisUtils.jedis.set("chat_bookkeeping_model_" + msg.getChatId(), "normal");
        // 设置记账费率 (两种模式通用)
        JedisUtils.jedis.set("chat_bookkeeping_rate_" + msg.getChatId(), "0.1");
        // 设置回U模式记账汇率 (普通模式是接口自动获取，回U模式是手动填写)
        JedisUtils.jedis.set("chat_bookkeeping_exchange_rate_" + msg.getChatId(), InterfaceUtils.getExchangeRate());

    }

    private void rateConversionHandler(Message msg){
        if (!authHandler(msg)) {
            return;
        }
        final String text = msg.getText();
        System.out.println("进入汇率转换！========================");
        System.out.println("text========================"+text);
        if (!text.matches("^z\\d+$") && !text.matches("^\\d+u$")) {
            return;
        }
        System.out.println("开始汇率转换！========================");
        final String resStr = HttpUtil.get("https://www.okx.com/v3/c2c/tradingOrders/books?t=1698847908986&quoteCurrency=cny&baseCurrency=usdt&side=sell&paymentMethod=all&userType=all&receivingAds=false");
        final JSONObject resJson = JSONUtil.parseObj(resStr);
        final JSONObject data = JSONUtil.parseObj(resJson.get("data"));
        final JSONArray sell = JSONUtil.parseArray(data.get("sell"));
        final List<SellVO> selllist = sell.toList(SellVO.class);
        final List<SellVO> list = selllist.stream()
                .sorted(Comparator.comparing(SellVO::getPrice).reversed())
                .collect(Collectors.toList()).subList(0,9);

        System.out.println("list====="+list);
        final StrBuilder ouyi = new StrBuilder();

        //实时价格计算
        final String divisor = ReUtil.get("\\d+",text,0);
        System.out.println("divisor====="+divisor);
        final BigDecimal exchangeRateDecimal = NumberUtil.toBigDecimal(list.get(2).getPrice());
        final BigDecimal divisorDecimal = NumberUtil.toBigDecimal(divisor);
        final BigDecimal divide = divisorDecimal.divide(exchangeRateDecimal, 2,RoundingMode.UP);
        final BigDecimal multiply = divisorDecimal.multiply(exchangeRateDecimal).setScale(2,RoundingMode.UP);
        list.forEach(item -> {
            ouyi.append(item.getPrice()).append("   ").append(item.getNickName()).append("\n");
        });
        if (text.matches("^z\\d+$")) {
            String describe = "<b>欧易(okx) USDT实时汇率</b>\n" +
                    "\n" +
                    ouyi +
                    "\n" +
                    "<b>实时价格（三档）：</b>\n" +
                    "<b>" + divisor+" 元 / "+exchangeRateDecimal+" = "+divide+" USDT</b>";
            sendText(msg.getChatId(), msg.getMessageId(), describe);

        }
        if (text.matches("^\\d+u$")) {
            String describe = "<b>欧易(okx) USDT实时汇率，</b>\n" +
                    "\n" +
                    ouyi +
                    "\n" +
                    "<b>实时价格（三档）：</b>\n" +
                    "<b>" + divisor+" USDT * "+exchangeRateDecimal+" = "+multiply+" 元</b>";
            sendText(msg.getChatId(), msg.getMessageId(), describe);
        }
    }

    private void clearDataCallBackHandlerEnd(CallbackQuery callbackQuery) {
        final String data = callbackQuery.getData();
        System.out.println("=============进入清除数据最后一步"+data);
        if ("cancel".equals(data)) {
            delMsg(callbackQuery.getMessage());
        }
        if ("今日数据-confirm".equals(data)) {
            final Long enterllen = JedisUtils.jedis.llen("chat_bookkeeping_enter_" + callbackQuery.getMessage().getChatId());
            final List<String> enterlrange = JedisUtils.jedis.lrange("chat_bookkeeping_enter_" + callbackQuery.getMessage().getChatId(),
                    0, enterllen - 1);
            System.out.println("enterlrange======="+enterlrange);

            enterlrange.forEach(item -> {
                if (ReUtil.contains("^"+ DateUtil.today(),item)) {
                    JedisUtils.jedis.lrem("chat_bookkeeping_enter_" + callbackQuery.getMessage().getChatId(),
                            0, item);
                }
            });

            final Long outerllen = JedisUtils.jedis.llen("chat_bookkeeping_outer_" + callbackQuery.getMessage().getChatId());
            final List<String> outerlrange = JedisUtils.jedis.lrange("chat_bookkeeping_outer_" + callbackQuery.getMessage().getChatId(),
                    0, outerllen - 1);
            outerlrange.forEach(item -> {
                if (ReUtil.contains("^"+ DateUtil.today(),item)) {
                    JedisUtils.jedis.lrem("chat_bookkeeping_outer_" + callbackQuery.getMessage().getChatId(),
                            0, item);
                }
            });
        }
        if ("全部数据-confirm".equals(data)) {
            JedisUtils.jedis.del("chat_bookkeeping_enter_" + callbackQuery.getMessage().getChatId());
            JedisUtils.jedis.del("chat_bookkeeping_outer_" + callbackQuery.getMessage().getChatId());
        }
    }

    private InlineKeyboardMarkup clearDataInlineBtnHandler(Message msg,String data) {

        List<InlineKeyboardButton> buttons = new ArrayList<>();
        InlineKeyboardButton todayButton = new InlineKeyboardButton("今日数据");
        todayButton.setText("今日数据");
        todayButton.setCallbackData("今日数据");

        InlineKeyboardButton allButton = new InlineKeyboardButton("全部数据");
        allButton.setText("全部数据");
        allButton.setCallbackData("全部数据");

        buttons.add(todayButton);
        buttons.add(allButton);

        List<InlineKeyboardButton> secondRowButtons = new ArrayList<>();
        InlineKeyboardButton cancelButton = new InlineKeyboardButton("❌取消操作");
        cancelButton.setText("❌取消操作");
        cancelButton.setCallbackData("cancel");
        secondRowButtons.add(cancelButton);

        List<InlineKeyboardButton> thirdRowButtons = new ArrayList<>();
        InlineKeyboardButton confirmButton = new InlineKeyboardButton("✅确认清除");
        confirmButton.setText("✅确认清除");
        confirmButton.setCallbackData(data+"-confirm");
        thirdRowButtons.add(confirmButton);

        InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
        List<List<InlineKeyboardButton>> keyboard = new ArrayList<>();
        keyboard.add(buttons);
        keyboard.add(secondRowButtons);
        keyboard.add(thirdRowButtons);

        inlineKeyboardMarkup.setKeyboard(keyboard);
        return inlineKeyboardMarkup;
    }


    private void clearDataCallBackHandler(CallbackQuery callbackQuery) {
        if (Objects.nonNull(callbackQuery)) {
            System.out.println("清除数据=============" + callbackQuery.getData());
            if ("今日数据".equals(callbackQuery.getData()) || "全部数据".equals(callbackQuery.getData())) {
                editMsgTxt(callbackQuery.getMessage(), getModelText(callbackQuery.getMessage()),
                        clearDataInlineBtnHandler(callbackQuery.getMessage(),callbackQuery.getData()));
            }
        }

    }

    private void clearDataHandler(Message msg) {
        if ("清除数据".equals(msg.getText())) {

            String describe = "<b>请选择清除数据类型！</b>\n" +
                    "本消息（30秒自毁）";


            List<InlineKeyboardButton> buttons = new ArrayList<>();
            InlineKeyboardButton todayButton = new InlineKeyboardButton();
            InlineKeyboardButton allButton = new InlineKeyboardButton();

            todayButton.setText("今日数据");
            allButton.setText("全部数据");

            todayButton.setCallbackData("今日数据");
            allButton.setCallbackData("全部数据");
            buttons.add(todayButton);
            buttons.add(allButton);

            sendInlineKeyboard(msg.getChatId(), describe, buttons, Boolean.TRUE);

        }
    }

    private void errorCorrectionHandler(Message msg) {
        if (msg.getText().matches("^入款\\-\\d+$")) {
            final String enter = ReUtil.get("^入款\\-\\d+$", msg.getText(), 0);
            JedisUtils.jedis.lpush("chat_bookkeeping_enter_error" + msg.getChatId(),
                    DateUtil.now() + "_" + enter.substring(2));
            // todo 还没有在结果减去异常总数，没有在返回的msg里展示纠错
            setMoneyTextHandler(msg);
        }
        if (msg.getText().matches("^下发\\-\\d+$")) {
            final String outer = ReUtil.get("^下发\\-\\d+$", msg.getText(), 0);
            JedisUtils.jedis.lpush("chat_bookkeeping_outer_error" + msg.getChatId(),
                    DateUtil.now() + "_" + outer.substring(2));
            // todo 还没有在结果减去异常总数，没有在返回的msg里展示纠错
            setMoneyTextHandler(msg);
        }
    }

    private void setMoneyHandler(Message msg) {
        if (!authHandler(msg)) {
            return;
        }

        // 增加
        if (msg.getText().matches("^\\+\\d+$")) {
            System.out.println("增加费率汇率设置====================");
            final String enter = ReUtil.get("\\d+", msg.getText(), 0);
            JedisUtils.jedis.lpush("chat_bookkeeping_enter_" + msg.getChatId(),
                    DateUtil.now() + "_" + enter);
            sendText(msg.getChatId(), msg.getMessageId(), setMoneyTextHandler(msg));
        }
        // 减少
        if (msg.getText().matches("^\\-\\d+$")) {
            final String outer = ReUtil.get("\\d+", msg.getText(), 0);
            JedisUtils.jedis.lpush("chat_bookkeeping_outer_" + msg.getChatId(),
                    DateUtil.now() + "_" + outer);
            sendText(msg.getChatId(), msg.getMessageId(), setMoneyTextHandler(msg));
        }


    }


    private String setMoneyTextHandler(Message msg) {
        // 入账模式
        final String model = JedisUtils.jedis.get("chat_bookkeeping_model_" + msg.getChatId());
        final String ratePercentage = JedisUtils.jedis.get("chat_bookkeeping_rate_" + msg.getChatId());
        final String exchangeRate = JedisUtils.jedis.get("chat_bookkeeping_exchange_rate_" + msg.getChatId());

        final BigDecimal rate = NumberUtil.toBigDecimal(ratePercentage).divide(NumberUtil.toBigDecimal(100),4, RoundingMode.HALF_UP);
        System.out.println("rate========+" + rate);

        // 获取入款list
        final Long enterLen = JedisUtils.jedis.llen("chat_bookkeeping_enter_" + msg.getChatId());
        final List<String> enterList = JedisUtils.jedis.lrange("chat_bookkeeping_enter_" + msg.getChatId(), 0, enterLen - 1);
        final StrBuilder enterListStr = new StrBuilder();
        List<BigDecimal> enterTotalList = new ArrayList<>();

        // 入款总金额
        enterList.forEach(item -> {
            final String[] split = item.split("_");
            enterListStr.append(split[0]).append("   ").append(split[1]).append("\n");
            enterTotalList.add(BigDecimal.valueOf(Double.parseDouble(split[1])));
        });

        final BigDecimal enterTotal = NumberUtil.add(ArrayUtil.toArray(enterTotalList, BigDecimal.class)).setScale(2);

        /*// 获取入款纠错list
        final Long enterErrLen = JedisUtils.jedis.llen("chat_bookkeeping_enter_err" + msg.getChatId());
        final List<String> enterErrList = JedisUtils.jedis.lrange("chat_bookkeeping_enter_err" + msg.getChatId(), 0, enterErrLen - 1);
        // 入款纠错总金额
        BigDecimal enterErrTotal = BigDecimal.ZERO;
        enterErrList.forEach(item -> {
            final String[] split = item.split("-");
            enterErrTotal.add(BigDecimal.valueOf(Double.parseDouble(split[1])),MathContext.UNLIMITED);
        });*/

        // 获取下发款list
        final Long outerLen = JedisUtils.jedis.llen("chat_bookkeeping_outer_" + msg.getChatId());
        final List<String> outerList = JedisUtils.jedis.lrange("chat_bookkeeping_outer_" + msg.getChatId(), 0, enterLen - 1);
        // 下发总金额
        final StrBuilder outerListStr = new StrBuilder();
        List<BigDecimal> outerTotalList = new ArrayList<>();

        outerList.forEach(item -> {
            final String[] split = item.split("_");
            outerListStr.append(split[0]).append("   ").append("-").append(split[1]).append("\n");
            outerTotalList.add(BigDecimal.valueOf(Double.parseDouble(split[1])));
        });
        final BigDecimal outerTotal = NumberUtil.add(ArrayUtil.toArray(outerTotalList, BigDecimal.class)).setScale(2);

/*
        // 获取下发纠错list
        final Long outerErrLen = JedisUtils.jedis.llen("chat_bookkeeping_outer_err" + msg.getChatId());
        final List<String> outerErrList = JedisUtils.jedis.lrange("chat_bookkeeping_outer_err" + msg.getChatId(), 0, outerErrLen - 1);
        // 下发纠错总金额
        BigDecimal outerErrTotal = BigDecimal.ZERO;
        outerErrList.forEach(item -> {
            final String[] split = item.split("-");
            outerErrTotal.add(BigDecimal.valueOf(Double.parseDouble(split[1])),MathContext.UNLIMITED);
        });*/


        // 手续费
        final BigDecimal handlingFees = enterTotal.multiply(rate).setScale(2);

        if ("normal".equals(model)) {
            // 应下金额
            final BigDecimal shouldTotal = enterTotal.subtract(handlingFees).setScale(2);
            // 未下金额
            final BigDecimal absenceTotal = shouldTotal.subtract(outerTotal).setScale(2);

            return "-------普通模式-------\n" +
                    DateUtil.today() + " 日小记\n" +
                    "\n" +
                    "入款： " + enterLen + " 笔\n" +
                    enterListStr +
                    "\n" +
                    "下发： " + outerLen + " 笔\n" +
                    outerListStr +
                    "\n" +
                    "--------------------------\n" +
                    "当前费率：" + ratePercentage + "  %\n" +
                    "入款金额：" + enterTotal + " 元\n" +
                    "应下金额：" + shouldTotal + " 元\n" +
                    "已下金额：" + outerTotal + " 元\n" +
                    "未下金额：" + absenceTotal + " 元\n" +
                    "\n" +
                    "手续费用：" + handlingFees + " 元";
        }


        if ("huiU".equals(model)) {
            final BigDecimal shouldTotal = enterTotal.divide(BigDecimal.valueOf(Double.parseDouble(exchangeRate)), 2, BigDecimal.ROUND_UP);
            return "-------回U模式------\n" +
                    DateUtil.today() + " 日小记\n" +
                    "\n" +
                    "入款： " + enterLen + " 笔\n" +
                    enterListStr +
                    "\n" +
                    "下发： " + outerLen + " 笔\n" +
                    outerListStr +
                    "\n" +
                    "--------------------------\n" +
                    "当前汇率：" + exchangeRate + "  %\n" +
                    "入款金额：" + enterTotal + " 元  \n" +
                    "应下金额：" + shouldTotal + " U\n" +
                    "已下金额：" + outerTotal + " U\n" +
                    "未下金额：" + shouldTotal.subtract(outerTotal).setScale(2) + " U\n" +
                    "\n" +
                    "手续费用： 0.00 元";
        }
        return "";
    }

    private void setUpRateHandler(Message msg) {
        System.out.println("========进入设置费率");
        if (!authHandler(msg)) {
            return;
        }
        if (msg.getText().matches("^设置费率(([1-9]?\\d(\\.\\d{1,2})?)|100|100.00)$")) {
            System.out.println("========开始设置费率");
            final String rate = ReUtil.get("^设置费率(([1-9]?\\d(\\.\\d{1,2})?)|100|100.00)$", msg.getText(), 0);
            System.out.println("========费率"+rate);
            JedisUtils.jedis.set("chat_bookkeeping_rate_" + msg.getChatId(), rate.substring(4));
            sendText(msg.getChatId(), msg.getMessageId(), "费率修改成功");
            return;
        }
        if (msg.getText().matches("^设置汇率(([1-9]?\\d(\\.\\d{1,2})?)|100|100.00)$")) {
            System.out.println("==============开始设置汇率");
            final String rate = ReUtil.get("^设置汇率(([1-9]?\\d(\\.\\d{1,2})?)|100|100.00)$", msg.getText(), 0);
            System.out.println("==============汇率"+rate);
            JedisUtils.jedis.set("chat_bookkeeping_exchange_rate_" + msg.getChatId(), rate.substring(4));
            sendText(msg.getChatId(), msg.getMessageId(), "汇率修改成功");
        }
    }

    private Boolean robotIsAdmin(Long chatId) {
        final GetChatAdministrators getChatAdministrators = GetChatAdministrators.builder().chatId(String.valueOf(chatId)).build();
        try {
            final ArrayList<ChatMember> members = execute(getChatAdministrators);
            for (ChatMember member : members) {
                if (member.getUser().getIsBot()) {
                    return true;
                }
            }
        } catch (TelegramApiException e) {
            throw new RuntimeException(e);
        }
        System.out.println("===========机器人不是管理员");
        return false;
    }

    private void groupAuthTextHandler(Message msg) {
        final String text = msg.getText().trim();
        final String userId = String.valueOf(msg.getFrom().getId());
        String nickName = msg.getFrom().getFirstName() + msg.getFrom().getLastName();
        final Message replyMessage = msg.getReplyToMessage();
        if ("开始记账".equals(text)) {
            System.out.println("===========开始记账");
            final String s = JedisUtils.jedis.get("auth_chat_admin_" + msg.getChatId());
            // 已存在最高权限用户
            if (StrUtil.isNotBlank(s)) {
                return;
            }
            // 设置最高权限用户
            JedisUtils.jedis.set("auth_chat_admin_" + msg.getChatId(), userId);
            initData(msg);
            sendText(msg.getChatId(), msg.getMessageId(), "设置成功,新增管理员" + nickName);
        } else if ("设置操作人".equals(text) && Objects.nonNull(replyMessage)) {
            if (!authHandler(msg)) {
                return;
            }
            final String admin = JedisUtils.jedis.get("auth_chat_admin_" + msg.getChatId());
            final User replyUser = replyMessage.getFrom();
            final String replyUserName = replyUser.getFirstName().concat(StrUtil.isNotBlank(replyUser.getLastName()) ? replyUser.getLastName() : "");
            // 如果要给admin授权，提示操作人为管理员
            if (admin.equals(String.valueOf(replyUser.getId()))) {
                sendText(msg.getChatId(), msg.getMessageId(), replyUserName + "已为管理员");
                return;
            }

            final Long llen = JedisUtils.jedis.llen("auth_chat_users_" + msg.getChatId());
            final List<String> users = JedisUtils.jedis.lrange("auth_chat_users_" + msg.getChatId(), 0, llen - 1);
            // 如果存在该用户，提示操作人为管理员
            if (CollectionUtil.isNotEmpty(users)) {
                if (users.contains(String.valueOf(replyUser.getId()))) {
                    sendText(msg.getChatId(), msg.getMessageId(), replyUserName + "已为管理员");
                    return;
                }
            }
            JedisUtils.jedis.lpush("auth_chat_users_" + msg.getChatId(), String.valueOf(replyUser.getId()));
            sendText(msg.getChatId(), msg.getMessageId(), "设置成功,新增管理员" + replyUserName);

        } else if ("移除操作人".equals(text)) {
            final String admin = JedisUtils.jedis.get("auth_chat_admin_" + msg.getChatId());

            // 只有最高权限用户可以移除操作人
            if (String.valueOf(userId).equals(admin)) {
                final Long llen = JedisUtils.jedis.llen("auth_chat_users_" + msg.getChatId());
                final List<String> users = JedisUtils.jedis.lrange("auth_chat_users_" + msg.getChatId(), 0, llen - 1);

                remove(msg, users, replyMessage);
            }
        } else if ("设置全部人".equals(msg.getText())) {
            final String admin = JedisUtils.jedis.get("auth_chat_admin_" + msg.getChatId());
            if (admin.equals(userId)) {
                final GetChat build = GetChat.builder().chatId(String.valueOf(msg.getChatId())).build();
                try {
                    final Chat chat = execute(build);
                    System.out.println("chat=================" + chat);
                } catch (TelegramApiException e) {
                    throw new RuntimeException(e);
                }
            }
        } else if ("移除全部人".equals(msg.getText())) {
            final String admin = JedisUtils.jedis.get("auth_chat_admin_" + msg.getChatId());
            if (admin.equals(userId)) {
                JedisUtils.jedis.del("auth_chat_users_" + msg.getChatId());
                sendText(msg.getChatId(), msg.getMessageId(), "移除所有人成功");
            }
        }
    }

    private void remove(Message msg, List<String> users, Message replyMessage) {
        final User replyUser = replyMessage.getFrom();
        assert replyUser != null;
        // redis里边没有这个要删除的人
        if (!users.contains(String.valueOf(replyUser.getId()))) {
            System.out.println("没有要移除的用户==========");
            return;
        }
        if (CollectionUtil.isNotEmpty(users)) {
            users.remove(String.valueOf(replyUser.getId()));
        }

        String nickname = replyUser.getFirstName().concat(StrUtil.isNotBlank(replyUser.getLastName()) ? replyUser.getLastName() : "");

        JedisUtils.jedis.del("auth_chat_users_" + msg.getChatId());
        if (CollectionUtil.isNotEmpty(users)) {
            JedisUtils.jedis.lpush("auth_chat_users_" + msg.getChatId(), ArrayUtil.toArray(users,String.class));
        }
        sendText(msg.getChatId(), msg.getMessageId(), "已移除操作人" + nickname);
    }

    private Boolean authHandler(Message msg) {
        final String userId = String.valueOf(msg.getFrom().getId());
        final String admin = JedisUtils.jedis.get("auth_chat_admin_" + msg.getChatId());
        if (userId.equals(admin)) {
            return Boolean.TRUE;
        }
        final Long llen = JedisUtils.jedis.llen("auth_chat_users_" + msg.getChatId());
        final List<String> users = JedisUtils.jedis.lrange("auth_chat_users_" + msg.getChatId(), 0, llen - 1);

        if (CollectionUtil.isNotEmpty(users)) {
            if (users.contains(userId)) {
                return Boolean.TRUE;
            }
        }
        System.out.println("============鉴权失败===============");
        return Boolean.FALSE;
    }

    private Boolean authHandler(Message msg,String userId) {
        final String admin = JedisUtils.jedis.get("auth_chat_admin_" + msg.getChatId());
        if (userId.equals(admin)) {
            return Boolean.TRUE;
        }
        final Long llen = JedisUtils.jedis.llen("auth_chat_users_" + msg.getChatId());
        final List<String> users = JedisUtils.jedis.lrange("auth_chat_users_" + msg.getChatId(), 0, llen - 1);

        if (CollectionUtil.isNotEmpty(users)) {
            if (users.contains(userId)) {
                return Boolean.TRUE;
            }
        }
        System.out.println("============鉴权失败===============");
        return Boolean.FALSE;
    }


    private void bookkeepingCallbackHandler(CallbackQuery callbackQuery) {
        if (Objects.nonNull(callbackQuery)) {
            final Message msg = callbackQuery.getMessage();
            System.out.println("callbackQueryData=============" + callbackQuery.getData());

            if ("普通模式".equals(callbackQuery.getData())) {
                JedisUtils.jedis.set("chat_bookkeeping_model_" + msg.getChatId(), "normal");
                editMsgTxt(callbackQuery.getMessage(), getModelText(callbackQuery.getMessage()),modelInlineBtnHandler(callbackQuery.getMessage()));
                return;
            }
            if ("回U模式".equals(callbackQuery.getData())) {
                JedisUtils.jedis.set("chat_bookkeeping_model_" + msg.getChatId(), "huiU");
                // 费率自动归0
                JedisUtils.jedis.set("chat_bookkeeping_rate_" + msg.getChatId(), "0");
                System.out.println("=========设为回U模式");
                editMsgTxt(callbackQuery.getMessage(), getModelText(callbackQuery.getMessage()),modelInlineBtnHandler(callbackQuery.getMessage()));
            }
        }

    }

    private InlineKeyboardMarkup modelInlineBtnHandler(Message msg) {

        // 获取记账模式
        final String model = JedisUtils.jedis.get("chat_bookkeeping_model_" + msg.getChatId());

        List<InlineKeyboardButton> buttons = new ArrayList<>();
        List<InlineKeyboardButton> secondRowButtons = new ArrayList<>();

        InlineKeyboardButton normalButton = new InlineKeyboardButton("普通模式");
        InlineKeyboardButton uButton = new InlineKeyboardButton("回U模式");

        InlineKeyboardButton realTimeButton = new InlineKeyboardButton();
        InlineKeyboardButton manualButton = new InlineKeyboardButton();


        if ("normal".equals(model)) {
            normalButton.setText("普通模式✅");
            uButton.setText("回U模式");
            normalButton.setCallbackData("普通模式✅");
            uButton.setCallbackData("回U模式");

            realTimeButton.setText("实时汇率✅");
            manualButton.setText("手动汇率");
        }
        if ("huiU".equals(model)) {
            normalButton.setText("普通模式");
            uButton.setText("回U模式✅");
            normalButton.setCallbackData("普通模式");
            uButton.setCallbackData("回U模式✅");

            realTimeButton.setText("实时汇率");
            manualButton.setText("手动汇率✅");

        }
        realTimeButton.setCallbackData("实时汇率");
        manualButton.setCallbackData("手动汇率");

        buttons.add(normalButton);
        buttons.add(uButton);

        secondRowButtons.add(realTimeButton);
        secondRowButtons.add(manualButton);

        InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
        List<List<InlineKeyboardButton>> keyboard = new ArrayList<>();
        keyboard.add(buttons);
        keyboard.add(secondRowButtons);

        inlineKeyboardMarkup.setKeyboard(keyboard);
        return inlineKeyboardMarkup;
    }

    private String getModelText(Message msg) {
        // 获取记账模式
        final String model = JedisUtils.jedis.get("chat_bookkeeping_model_" + msg.getChatId());
        // 获取记账费率
        final String rate = JedisUtils.jedis.get("chat_bookkeeping_rate_" + msg.getChatId());
        // 获取普通模式记账汇率
        String exchangeRate = InterfaceUtils.getExchangeRate();
        // 获取回U模式记账汇率
        String uExchangeRate = JedisUtils.jedis.get("chat_bookkeeping_exchange_rate_" + msg.getChatId());

        if ("normal".equals(model)) {
            return "<b>记账设置</b> （30秒自毁）\n" +
                    "\n" +
                    "模式：<b>（普通模式-默认）</b>\n" +
                    "汇率：<b>（大宗实时  " + exchangeRate + "）</b>\n" +
                    "费率：<b>" + rate + " %</b>\n" +
                    "\n" +
                    "\uD83C\uDD98<b>切换模式前，务必清除数据！</b>";
        }

        if ("huiU".equals(model)) {
            return "<b>记账设置</b> （30秒自毁）\n" +
                    "\n" +
                    "模式：<b>（卡接回U-特殊）</b>\n" +
                    "汇率：<b>（手动设置  " + uExchangeRate + "）</b>\n" +
                    "费率：<b>" + rate + " %\n</b>" +
                    "\n" +
                    "\uD83C\uDD98<b>切换模式前，务必清除数据！</b>";
        }
        return "";
    }

    private void bookkeepingModelHandler(Message msg) {
        if (!authHandler(msg)) {
            return;
        }
        final String text = msg.getText();

        if ("设置".equals(text)) {
            final String model = JedisUtils.jedis.get("chat_bookkeeping_model_" + msg.getChatId());

            List<InlineKeyboardButton> buttons = new ArrayList<>();
            List<InlineKeyboardButton> secondRowButtons = new ArrayList<>();


            InlineKeyboardButton normalButton = new InlineKeyboardButton();
            InlineKeyboardButton uButton = new InlineKeyboardButton();

            InlineKeyboardButton realTimeButton = new InlineKeyboardButton();
            InlineKeyboardButton manualButton = new InlineKeyboardButton();

            if ("normal".equals(model)) {
                normalButton.setText("普通模式✅");
                uButton.setText("回U模式");

                realTimeButton.setText("实时汇率✅");
                manualButton.setText("手动汇率");
            }
            if ("huiU".equals(model)) {
                normalButton.setText("普通模式");
                uButton.setText("回U模式✅");

                realTimeButton.setText("实时汇率");
                manualButton.setText("手动汇率✅");
            }

            normalButton.setCallbackData("普通模式");
            uButton.setCallbackData("回U模式");

            realTimeButton.setCallbackData("实时汇率");
            manualButton.setCallbackData("手动汇率");

            buttons.add(normalButton);
            buttons.add(uButton);

            secondRowButtons.add(realTimeButton);
            secondRowButtons.add(manualButton);

            final ArrayList<List<InlineKeyboardButton>> keyboard = new ArrayList<>();
            keyboard.add(buttons);
            keyboard.add(secondRowButtons);

            sendInlineKeyboardMultilineRow(msg.getChatId(), getModelText(msg), keyboard, Boolean.TRUE);

        }
//        https://www.okx.com/api/v5/market/exchange-rate
    }


    private void fourOperationsHandler(Message msg) {
        // 正则运算
        if (msg.getText().matches("^(\\-?\\d+(\\.\\d+)?)([\\+\\-\\*/](\\-?\\d+(\\.\\d+)?))+$")) {

            try {
                sendText(msg.getChatId(), msg.getMessageId(), "计算结果: " + MathUtils.fourOperations(msg.getText()));
            } catch (ScriptException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void createButton() {
        InlineKeyboardButton start = InlineKeyboardButton.builder()
                .text("开始记账")
                .url("https://t.me/guanbo_bot/?startgroup=1")
                .callbackData("/choose-group")
                .build();

        // 设置初次使用button
        List<InlineKeyboardButton> buttons = new ArrayList<>();
        buttons.add(start);
        keyboardM1 = InlineKeyboardMarkup.builder()
                .keyboardRow(buttons).build();


    }

    private void keyboardTextHandler(Message msg) {
        String txt = msg.getText();
        if ("使用教程".equals(txt)) {
            String tutorial = "1.✅激活机器人\n" +
                    "将机器人邀请进群后，发送消息 开始 激活机器人\n" +
                    "第一个激活机器人的用户自动获得最高使用权限\n" +
                    "\n" +
                    "2.\uD83D\uDC64设置使用权限\n" +
                    "拥有使用权限用户回复消息 设置操作人 给其他用户,即可授予使用权限\n" +
                    "回复消息 移除操作人 即可取消用户使用权限\n" +
                    "\n" +
                    "3.\uD83D\uDCDD记账功能\n" +
                    "使用前先输入“设置”选择记账模式，“普通模式”适合卡卡跑分，汇率自动按照欧意大宗实时计算。“回U模式”适合卡接回U，汇率手动设置，费率自动归零，选择好模式后，发送消息 +金额 -金额 ，例如发送 +100 -100，即可使用记账功能，如出现入款或下发错误，入款纠错命令为“入款-金额，下发纠错命令为”下发-金额“。例如：实际入款10000，却输入”+20000“，那么再输入”入款-10000“，即可纠错！，下发反之！\n" +
                    "机器人只会统计当日账单\n" +
                    "\n" +
                    "4.清除记账数据\n" +
                    "发送消息 清除数据 ,选择您要清除的数据类型\n" +
                    "\n" +
                    "5.\uD83E\uDDEE计算器\n" +
                    "支持加减乘除运算，机器人会自动计算结果并发送消息\n" +
                    "\n" +
                    "6.♻\uFE0F汇率换算\n" +
                    "发送文字 金额+u 或 z+金额,即可按照实时汇率换算成U或人民币\n" +
                    "例如 z100 200u\n" +
                    "\n" +
                    "7.\uD83D\uDD00汇率&费率设置\n" +
                    "发送消息 设置费率+数字 会修改群内记账费率\n" +
                    "发送消息 设置汇率+数字 会修改群内记账汇率\n" +
                    "例如发送 设置汇率7 设置费率0.1";
            sendText(msg.getChatId(), msg.getMessageId(), tutorial);
        } else if ("技术支持".equals(txt)) {
            List<InlineKeyboardButton> buttons = new ArrayList<>();
            InlineKeyboardButton technicalSupport = new InlineKeyboardButton("技术支持");
            technicalSupport.setUrl("https://t.me/ndjd7375");
            buttons.add(technicalSupport);
            String text = "当前版本 v1.0\n" +
                    "\n" +
                    "遇到问题可以随时联系我\uD83D\uDC47";
            sendInlineKeyboard(msg.getChatId(), text, buttons, Boolean.FALSE);
        } else if ("开始使用".equals(txt)) {
            List<InlineKeyboardButton> buttons = new ArrayList<>();
            InlineKeyboardButton technicalSupport = new InlineKeyboardButton("开始记账");
            technicalSupport.setUrl("https://t.me/guanbo_bot/?startgroup=1");
            buttons.add(technicalSupport);
            String text = "\uD83E\uDD16欢迎使用记账机器人，快把我加入群组吧！";
            sendInlineKeyboard(msg.getChatId(), text, buttons, Boolean.FALSE);
        }
        return;

    }

    public void sendText(Long chatId, Integer msgId, String what) {
        SendMessage sm = SendMessage.builder()
                .replyToMessageId(msgId)
                .parseMode("HTML")
                .chatId(chatId.toString()) //Who are we sending a message to
                .text(what).build();    //Message content
        try {
            execute(sm);                        //Actually sending the message
        } catch (TelegramApiException e) {
            throw new RuntimeException(e);      //Any error will be printed here
        }
    }

    public void sendButton(Long who, String txt, InlineKeyboardMarkup kb) {
        SendMessage sm = SendMessage.builder().chatId(who.toString())
                .parseMode("HTML").text(txt)
                .replyMarkup(kb).build();

        try {
            execute(sm);
        } catch (TelegramApiException e) {
            throw new RuntimeException(e);
        }
    }

    private void delMsg(Message msg) {
        final DeleteMessage build = DeleteMessage.builder().chatId(String.valueOf(msg.getChatId()))
                .messageId(msg.getMessageId()).build();
        try {
            execute(build);
        } catch (TelegramApiException e) {
            throw new RuntimeException(e);
        }
    }


    public void sendCustomKeyboard(Long chatId) {
        SendMessage message = new SendMessage();
        message.setChatId(String.valueOf(chatId));
        message.setText("\uD83D\uDE80键盘已启动");
        // Create ReplyKeyboardMarkup object
        ReplyKeyboardMarkup keyboardMarkup = new ReplyKeyboardMarkup();
        keyboardMarkup.setResizeKeyboard(true);
        // Create the keyboard (list of keyboard rows)
        List<KeyboardRow> keyboard = new ArrayList<>();

        // Create a keyboard row
        KeyboardRow row = new KeyboardRow();
        // Set each button, you can also use KeyboardButton objects if you need something else than text
        row.add("使用教程");
        row.add("技术支持");
        // Add the first row to the keyboard
        keyboard.add(row);
        // Create another keyboard row
        row = new KeyboardRow();
        // Set each button for the second line
        row.add("开始使用");
        // Add the second row to the keyboard
        keyboard.add(row);
        // Set the keyboard to the markup
        keyboardMarkup.setKeyboard(keyboard);
        // Add it to the message
        message.setReplyMarkup(keyboardMarkup);

        try {
            // Send the message
            execute(message);
        } catch (TelegramApiException e) {
            e.printStackTrace();
        }
    }



    public void sendInlineKeyboard(Long chatId, String text, List<InlineKeyboardButton> buttons, Boolean isDel) {
        SendMessage message = new SendMessage();
        message.setChatId(String.valueOf(chatId));
        message.setText(text);
        message.setParseMode("HTML");

        // Create InlineKeyboardMarkup object
        InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
        // Create the keyboard (list of InlineKeyboardButton list)
        List<List<InlineKeyboardButton>> keyboard = new ArrayList<>();
        // Initialize each button, the text must be written
        keyboard.add(buttons);
        inlineKeyboardMarkup.setKeyboard(keyboard);

        // Add it to the message
        message.setReplyMarkup(inlineKeyboardMarkup);

        try {
            final Message execute = execute(message);
            if (isDel) {
                Timer timer = new Timer();
                TimerTask task = new TimerTask() {
                    public void run() {
                        // 在此处写入需要执行的代码
                        delMsg(execute);
                    }

                };
                timer.schedule(task, 30000);
            }

        } catch (TelegramApiException e) {
            e.printStackTrace();
        }
    }

    public void sendInlineKeyboardMultilineRow(Long chatId, String text, List<List<InlineKeyboardButton>> keyboard, Boolean isDel) {
        SendMessage message = new SendMessage();
        message.setChatId(String.valueOf(chatId));
        message.setText(text);
        message.setParseMode("HTML");

        // Create InlineKeyboardMarkup object
        InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
        // Create the keyboard (list of InlineKeyboardButton list)
        inlineKeyboardMarkup.setKeyboard(keyboard);

        // Add it to the message
        message.setReplyMarkup(inlineKeyboardMarkup);

        try {
            final Message execute = execute(message);
            if (isDel) {
                Timer timer = new Timer();
                TimerTask task = new TimerTask() {
                    public void run() {
                        // 在此处写入需要执行的代码
                        delMsg(execute);
                    }

                };
                timer.schedule(task, 30000);
            }

        } catch (TelegramApiException e) {
            e.printStackTrace();
        }
    }

    private void editMsgTxt(Message msg, String text,InlineKeyboardMarkup inlineKeyboardMarkup) {
        final EditMessageText build = EditMessageText.builder().chatId(String.valueOf(msg.getChatId()))
                .text(text)
                .parseMode("HTML")
                .messageId(msg.getMessageId())
                .replyMarkup(inlineKeyboardMarkup)
                .build();
        try {
            execute(build);
        } catch (TelegramApiException e) {
            throw new RuntimeException(e);
        }

    }

}
